<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <title>ChatGPT3.5-turbo</title>
    <link rel="shortcut icon" href="./img/snoopy-head.ico" type="image/x-icon">
    <!--  引入Vue-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!--  引入axios-->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <!--    美化页面-->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <!--  引入文件下载 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
    <!--  手机端适配 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <style>
        body {
            background-color: #f5f5f5;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        #app {
            display: flex;
            flex-direction: column;
            width: 50%;
            min-width: 400px;

        }

        /* 说明 */
        .text {
            margin: 14px 0;
        }

        /* 页面顶部 */
        .top {
            margin-top: 30px;
        }

        /* APIKEY */
        input {
            margin: 10px 0;
            text-align: center;
        }

        /* prompt */
        #input {
            white-space: pre-wrap;
            min-height: 100px;
            height: 100px;
            max-width: 100%;
            min-width: 100%;
        }

        button {
            margin: 10px 0;
            height: 50px;
        }

        #output {

            height: 300px;
        }

        /* 消息容器 */
        .message_container {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            width: 100%;
            overflow: auto;

        }

        /* 一条消息 */
        .message {
            flex-direction: row;
            align-items: flex-start;
            width: 100%;
            margin: 10px 0px;
            padding: 10px;
            background-color: #fff;
            border-radius: 10px;
        }

        /* 用户角色标签 */
        .message_role_user {
            border-radius: 5px;
            padding: 5px;
            color: white;
            text-align: center;
            width: 80px;
            background-color: #366ef4;
        }

        /* AI角色标签 */
        .message_role_ai {

            border-radius: 5px;
            padding: 5px;
            text-align: center;
            width: 80px;
            color: white;
            background-color: #f6685d;
        }

        /* 消息内容 */
        .message_content {
            margin: 20px 0;

        }

        /* 页面底部信息 */
        .information {
            width: 100%;
            display: flex;
            justify-content: space-evenly;
            margin: 30px 0;

        }
    </style>

</head>

<body>
    <div id="app">

        <h1 class="top" v-if="message_container.length>0">聊天记录</h1>

        <!-- 下载聊天记录，从message_container -->

        <div class="message_container">
            <div class="message" v-for="message in message_container">
                <div class="message_role_user" v-if="message.role==='user'">
                    用户
                </div>
                <div class="message_role_ai" v-else>
                    gpt-3.5
                </div>
                <div class="message_content" v-if="message.role==='user'" v-html="peocessMarkdownUser(message.content)">

                </div>
                <div class="message_content" v-else v-html="peocessMarkdown(message.content)">

                </div>
            </div>
        </div>
        <!-- 下载聊天记录按钮 -->
        <!--  -->
        <!-- 一行两个按钮 -->
        <div class="information" v-if="message_container.length>0">
            <button class="btn btn-primary" @click="downloadChatRecordTxt">下载.txt聊天记录</button>
            <button class="btn btn-primary" @click="downloadChatRecordMd">下载.md聊天记录</button>
        </div>
        <!-- 用户输入窗口， -->
        <h2 class="top">ChatGPT3.5-turbo</h2>
        <h2 v-if="message_container.length==0">使用说明</h2>
        <div class="introduction" v-if="message_container.length==0">
            <p>1.输入API-KEY</p>
            <p>2.输入问题，点击发送</p>
            <p>3.等待AI回复</p>
            <p>4.点击下载聊天记录</p>

        </div>
        <h2>请输入问题</h2>

        <textarea name="" id="input" v-model="input_string" cols="30" rows="10"></textarea>
        <button type="button" id="sendBtn" class="btn btn-primary" @click="send">发送</button>
        <!-- <h3>请输入API-KEY</h3>
        <input type="password" v-model="api_key"> -->



    </div>
</body>
<script>

    var app = new Vue({
        el: '#app',
        data: {
            input_string: '',
            api_key: '',
            message_container: [
            ],

        },
        created: function () {
            // 获取cookies中的APIKey
            this.getApiKey();
        },
        // lorem    
        methods: {
            getApiKey: function () {
                // 如果localStorage中已经有了apikey，则从localStorage中获取
                if (localStorage.getItem('apikey')) {
                    this.api_key = localStorage.getItem('apikey');
                } else {
                    // 如果localStorage中没有apikey，则弹出提示框让用户输入
                    var apikey = prompt("请输入API-Key：", "");
                    // 如果用户输入为空，一直弹出提示框
                    while (apikey === '') {
                        alert("请输入API-Key！");
                        apikey = prompt("请输入API-Key：", "");
                    }
                    // 将用户输入的apikey保存到localStorage中
                    localStorage.setItem('apikey', apikey);
                    this.api_key = apikey;
                }
            },

            send: function () {
                that = this;
                console.log(that.message_container)
                if (that.input_string[0] === '\n' || that.input_string[1] === '\t') {
                    that.input_string = that.input_string.slice(1);
                }
                // 输入为空
                if (that.input_string === '') {
                    alert("输入不能为空");
                    return;
                }
                tmp_message = { role: 'user', content: that.input_string };
                that.message_container.push(tmp_message);

                // 清空输入框
                that.input_string = '';
                // 禁用按钮
                document.getElementById("sendBtn").disabled = true;
                // 修改文字
                document.getElementById("sendBtn").innerText = "发送中";

                axios.post("https://api.openai.com/v1/chat/completions", {
                    model: 'gpt-3.5-turbo',
                    messages: that.message_container,
                    max_tokens: 4000,
                }, {
                    headers: {
                        Authorization: `Bearer ${that.api_key}`,
                        'Content-Type': 'application/json',
                    },
                })
                    .then((response) => {
                        console.log(response);
                        console.log(response.data.choices[0].message.content);
                        string_result = response.data.choices[0].message.content;
                        if (string_result[0] === '\n') {
                            string_result = string_result.slice(1);
                        }
                        tmp_message = { role: response.data.choices[0].message.role, content: string_result };
                        that.message_container.push(tmp_message);
                        // 滑到页面的底部
                        var message_container = document.getElementsByClassName("message_container")[0];
                        message_container.scrollTop = message_container.scrollHeight;
                        // 启用按钮
                        document.getElementById("sendBtn").disabled = false;
                        // 修改文字
                        document.getElementById("sendBtn").innerText = "发送";

                    })
                    .catch((error) => {
                        console.error(error);
                        alert("发送失败，请检查API-KEY是否正确，或者稍后再试，也有可能是网络问题，在中国大陆网络环境可能无法使用")
                        // 启用按钮
                        document.getElementById("sendBtn").disabled = false;
                        // 修改文字
                        document.getElementById("sendBtn").innerText = "发送";
                        // 删除最后一条消息
                        that.message_container.pop();
                    });

            },
            peocessMarkdownUser: function (string) {


                // 1.处理 < > /
                string = string.replace(/</g, "&lt;");
                string = string.replace(/>/g, "&gt;");
                string = string.replace(/\//g, "&#47;");

                // 2. 处理换行
                string = string.replace(/\n/g, "<br>");
                // 3. 处理粗体

                return string;
            },
            peocessMarkdown: function (string) {

                // 处理 < > /
                string = string.replace(/</g, "&lt;");
                string = string.replace(/>/g, "&gt;");
                string = string.replace(/\//g, "&#47;");

                // 将代码块内的特殊字符进行编码
                string = string.replace(/```(\w+)?([\s\S]*?)```/g, function (match, lang, code) {
                    code = code.replace(/</g, "&lt;");
                    code = code.replace(/>/g, "&gt;");
                    code = code.replace(/"/g, "&quot;");
                    code = code.replace(/'/g, "&#39;");

                    var language = "";
                    if (lang) {
                        language = ' class="language-' + lang + '"';
                    }

                    // return "<pre><code" + language + ">" + code + "</code></pre>";
                    return "<pre><code" + language + ">" + code + "</code></pre>";
                });


                // 1. 处理换行
                string = string.replace(/\n/g, "<br>");
                // 2. 处理粗体
                string = string.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>");
                // 3. 处理斜体
                string = string.replace(/\*(.*?)\*/g, "<i>$1</i>");
                // 4. 处理链接
                string = string.replace(/\[(.*?)\]\((.*?)\)/g, "<a href='$2'>$1</a>");
                // 5. 处理图片
                string = string.replace(/\!\[(.*?)\]\((.*?)\)/g, "<img src='$2' alt='$1'>");

                // 7.处理表格
                string = string.replace(/\|(.*)\|/g, "<tr><td>$1</td></tr>");

                return string;
            },
            // 转换为TXT
            toTxt: function (obj) {
                // 将[{},{},{}]转换为用户可读的字符串，obj[i].content可能带有"\n"，然后role用中文来表示
                var string = "";
                string += "# 聊天记录\n\n时间：" + new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString()
                for (var i = 0; i < obj.length; i++) {
                    if (obj[i].role === "user") {
                        string += "用户：" + obj[i].content + "\n\n";
                    } else {
                        string += "机器人：" + obj[i].content + "\n\n";
                    }
                }
                return string;
            },
            // 转换为Markdown
            toMarkdown: function (obj) {
                // 将[{},{},{}]转换为用户可读的字符串，obj[i].content可能带有"\n"，然后role用中文来表示
                var string = "";
                string += "# 聊天记录\n\n时间：" + new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString()
                for (var i = 0; i < obj.length; i++) {
                    if (obj[i].role === "user") {
                        string += "## 用户\n\n" + obj[i].content + "\n\n";
                    } else {
                        string += "## 机器人\n\n" + obj[i].content + "\n\n";
                    }
                }
                return string;
            },
            // 下载聊天记录
            downloadChatRecordMd: function () {
                var that = this;
                // markdown
                var blob = new Blob([that.toMarkdown(that.message_container)], { type: "text/plain;charset=utf-8" });
                //var filename = 聊天记录-年月日时分秒
                var filename = "聊天记录" + new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString() + ".md";
                saveAs(blob, filename);

            },
            downloadChatRecordTxt: function () {
                var that = this;
                // txt
                var blob = new Blob([that.toTxt(that.message_container)], { type: "text/plain;charset=utf-8" });
                //var filename = 聊天记录-年月日时分秒
                var filename = "聊天记录" + new Date().toLocaleDateString() + "-" + new Date().toLocaleTimeString() + ".txt";
                saveAs(blob, filename);
            },
        }
    });

</script>

</html>